/** 弹窗支持拖拽 license by http://eleadmin.com */

/**
 * 初始化dialog的样式
 * @param dialogEl
 */
function initDialogStyle(dialogEl) {
  dialogEl.style.top = dialogEl.offsetTop + 'px';
  dialogEl.style.left = dialogEl.offsetLeft + 'px';
  dialogEl.style.bottom = 'auto';
  dialogEl.style.right = 'auto';
  dialogEl.style.margin = 0;
  dialogEl.style.position = 'relative';
  if (dialogEl.parentNode.hasAttribute('ele-resizable')) {
    dialogEl.style.display = 'inline-flex';
  } else {
    dialogEl.style.display = 'inline-block';
  }
}

/**
 * 弹窗拖拽指令
 */
const movableDirective = {
  bind: (el, binding) => {
    el.setAttribute('ele-movable', binding.value ? 'true' : '');
    el.addEventListener('mousedown', function(event) {
      // 全屏时不能拖拽
      if (el.classList.contains('ele-dialog-wrap-fullscreen')) {
        return;
      }
      const headerEl = el.querySelector('.el-dialog__header');
      const titleEl = headerEl.querySelector('.el-dialog__title');
      if (event.target !== headerEl && event.target !== titleEl) {
        return;
      }
      el.style.userSelect = 'none';
      const dialogEl = el.querySelector('.el-dialog');
      initDialogStyle(dialogEl);
      const moveOut = el.getAttribute('ele-movable');
      // 获取原始位置
      const downX = event.clientX;
      const downY = event.clientY;
      const downOL = dialogEl.offsetLeft;
      const downOT = dialogEl.offsetTop;

      // 鼠标移动事件
      const mousemoveFn = function(e) {
        let l = e.clientX - downX + downOL;
        let t = e.clientY - downY + downOT;
        // 边界判断
        if (moveOut !== 'true') {
          const screenWidth =
            document.documentElement.clientWidth || document.body.clientWidth;
          let limitL = screenWidth - dialogEl.clientWidth;
          if (l < 1) {
            l = 1;
          } else if (l > limitL - 1) {
            l = limitL - 1;
          }
          const screenHeight =
            document.documentElement.clientHeight || document.body.clientHeight;
          let limitT = screenHeight - dialogEl.clientHeight;
          if (t > limitT - 2) {
            t = limitT - 2;
          }
          if (t < 1) {
            t = 1;
          }
        }
        // 移动dialog
        dialogEl.style.left = l + 'px';
        dialogEl.style.top = t + 'px';
      };

      // 鼠标抬起事件
      const mouseupFn = function() {
        el.style.userSelect = null;
        document.removeEventListener('mousemove', mousemoveFn);
        document.removeEventListener('mouseup', mouseupFn);
      };

      // 添加鼠标事件监听
      document.addEventListener('mousemove', mousemoveFn);
      document.addEventListener('mouseup', mouseupFn);
    });
  },
  update: (el, binding) => {
    el.setAttribute('ele-movable', binding.value ? 'true' : '');
  }
};

/**
 * 弹窗拉伸指令
 */
const resizableDirective = {
  inserted: (el) => {
    el.setAttribute('ele-resizable', '');
    el.addEventListener('mousedown', function(event) {
      if (el.classList.contains('ele-dialog-wrap-fullscreen')) {
        return;
      }
      const dialogEl = el.querySelector('.el-dialog');
      const limitX = dialogEl.clientWidth + dialogEl.offsetLeft - el.scrollLeft;
      const limitY = dialogEl.clientHeight + dialogEl.offsetTop - el.scrollTop;
      if (
        event.clientX > limitX ||
        limitX - event.clientX > 10 ||
        event.clientY > limitY ||
        limitY - event.clientY > 10
      ) {
        return;
      }
      el.style.userSelect = 'none';
      initDialogStyle(dialogEl);
      // 获取原始位置
      const downX = event.clientX;
      const downY = event.clientY;
      const downW = dialogEl.clientWidth;
      const downH = dialogEl.clientHeight;

      // 鼠标移动事件
      const mousemoveFn = function(e) {
        const w = e.clientX - downX + downW;
        const h = e.clientY - downY + downH;
        // 移动dialog
        dialogEl.style.width = (w < 260 ? 260 : w) + 'px';
        dialogEl.style.height = (h < 160 ? 160 : h) + 'px';
      };

      // 鼠标抬起事件
      const mouseupFn = function() {
        el.style.userSelect = null;
        document.removeEventListener('mousemove', mousemoveFn);
        document.removeEventListener('mouseup', mouseupFn);
      };

      // 添加鼠标事件监听
      document.addEventListener('mousemove', mousemoveFn);
      document.addEventListener('mouseup', mouseupFn);
    });
  }
};

/**
 * 弹窗最大化切换
 * @param el
 * @param fullscreen
 */
function toggleFullscreen(el, fullscreen) {
  const iconEl = el.querySelector('.ele-dialog__fullscreen');
  if (typeof fullscreen === 'undefined') {
    el.classList.toggle('ele-dialog-wrap-fullscreen');
    iconEl.classList.toggle('el-icon-full-screen');
    iconEl.classList.toggle('el-icon-_compress');
  } else if (fullscreen) {
    el.classList.add('ele-dialog-wrap-fullscreen');
    iconEl.classList.remove('el-icon-full-screen');
    iconEl.classList.add('el-icon-_compress');
  } else {
    el.classList.remove('ele-dialog-wrap-fullscreen');
    iconEl.classList.add('el-icon-full-screen');
    iconEl.classList.remove('el-icon-_compress');
  }
}

/**
 * 弹窗全屏指令
 */
const maximizableDirective = {
  inserted: (el, binding) => {
    el.setAttribute('ele-maximizable', binding.value ? 'true' : '');
    // 添加最大化切换按钮
    const headerEl = el.querySelector('.el-dialog__header');
    const closeEl = headerEl.querySelector('.el-dialog__headerbtn');
    const maxEl = document.createElement('button');
    maxEl.setAttribute('type', 'button');
    maxEl.classList.add('el-dialog__headerbtn');
    const iconEl = document.createElement('i');
    iconEl.classList.add(
      'el-dialog__close',
      'ele-dialog__fullscreen',
      'el-icon',
      'el-icon-full-screen'
    );
    maxEl.appendChild(iconEl);
    if (closeEl) {
      headerEl.insertBefore(maxEl, closeEl);
    } else {
      headerEl.appendChild(maxEl);
    }

    // 绑定点击事件
    maxEl.addEventListener('click', function() {
      toggleFullscreen(el);
      maxEl.blur();
    });

    // 默认全屏
    if (binding.value) {
      toggleFullscreen(el, true);
    }
  },
  update: (el, binding) => {
    if ((binding.value ? 'true' : '') !== el.getAttribute('ele-maximizable')) {
      el.setAttribute('ele-maximizable', binding.value ? 'true' : '');
      toggleFullscreen(el, !!binding.value);
    }
  }
};

/**
 * 弹窗多层置顶指令
 */
const setTopDirective = {
  bind: (el) => {
    el.addEventListener('mousedown', function() {
      const wrapperEls = document.querySelectorAll('.el-dialog__wrapper');
      let zIndex = Number(el.style.zIndex);
      for (let i = 0; i < wrapperEls.length; i++) {
        const index = Number(wrapperEls[i].style.zIndex);
        if (wrapperEls[i] !== el && index >= zIndex) {
          zIndex = index + 1;
        }
      }
      if (zIndex > el.style.zIndex) {
        el.style.zIndex = zIndex;
      }
    });
  }
};

export {
  movableDirective,
  resizableDirective,
  maximizableDirective,
  setTopDirective
};

export default {
  install(Vue) {
    Vue.directive('dialog-movable', movableDirective);
    Vue.directive('dialog-resizable', resizableDirective);
    Vue.directive('dialog-maximizable', maximizableDirective);
    Vue.directive('dialog-set-top', setTopDirective);
  }
};
